package com.ssy.lingxi.contract.serviceimpl;

import cn.hutool.core.date.DateUtil;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.contract.api.model.vo.request.PurchaseViePriceAddVO;
import com.ssy.lingxi.contract.constant.Constants;
import com.ssy.lingxi.contract.entity.PurchaseViePriceDO;
import com.ssy.lingxi.contract.model.constant.CommonBooleanEnum;
import com.ssy.lingxi.contract.model.vo.common.request.PurchaseViePricePageVO;
import com.ssy.lingxi.contract.model.vo.common.response.PurchaseViePriceQueryVO;
import com.ssy.lingxi.contract.repository.PurchaseViePriceRepository;
import com.ssy.lingxi.contract.service.IFeignService;
import com.ssy.lingxi.contract.service.IPurchaseViePriceService;
import com.ssy.lingxi.message.api.constant.MessageTemplateCode;
import com.ssy.lingxi.message.api.vo.request.SystemMessageRequest;
import com.ssy.lingxi.report.api.enums.ContractManageOperateTypeEnum;
import com.ssy.lingxi.report.api.enums.OperateDataSourceEnum;
import com.ssy.lingxi.report.api.vo.request.OperateNoticeVO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 采购竞价合同接口实现
 * @author 伍将
 * @date 2021/3/15
 * @version 2.0.0
 */
@Service
public class PurchaseViePriceServiceImpl implements IPurchaseViePriceService {

    @Resource
    private PurchaseViePriceRepository repository;
    @Resource
    private IFeignService feignService;

    /**
     * 分页查询待创建采购竞价合同
     * @author 伍将
     * @date 2021/3/15
     * @param user: 当前登录用户
     * @param pageVO: 分页请求参数
     * @return 操作结果
     **/
    @Override
    public Wrapper<PageData<PurchaseViePriceQueryVO>> pageToBeCreate(UserLoginCacheDTO user, PurchaseViePricePageVO pageVO) {

        // 组装查询条件
        Specification<PurchaseViePriceDO> spec =  (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), user.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), user.getMemberRoleId()));
            list.add(criteriaBuilder.equal(root.get("isCreate").as(Long.class), CommonBooleanEnum.NO.getCode()));
            if (StringUtils.hasLength(pageVO.getStartTime())) {
                list.add(criteriaBuilder.greaterThan(root.get("awardTime").as(Long.class), DateUtil.parse(pageVO.getStartTime()).getTime()));
            }
            if (StringUtils.hasLength(pageVO.getEndTime())) {
                list.add(criteriaBuilder.lessThan(root.get("awardTime").as(Long.class), DateUtil.parse(pageVO.getEndTime()).getTime()));
            }
            if (StringUtils.hasLength(pageVO.getViePriceNO())) {
                list.add(criteriaBuilder.like(root.get("viePriceNO").as(String.class), "%" + pageVO.getViePriceNO().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getViePriceAbstract())) {
                list.add(criteriaBuilder.like(root.get("viePriceAbstract").as(String.class), "%" + pageVO.getViePriceAbstract().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getAwardName())) {
                list.add(criteriaBuilder.like(root.get("awardName").as(String.class), "%" + pageVO.getAwardName().trim() + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        // 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("awardTime").descending());

        Page<PurchaseViePriceDO> result = repository.findAll(spec, page);
        List<PurchaseViePriceQueryVO> resultList = result.getContent().stream().map(o -> {
            PurchaseViePriceQueryVO entity = new PurchaseViePriceQueryVO();
            entity.setId(o.getId());
            entity.setViePriceId(o.getViePriceId());
            entity.setViePriceNO(o.getViePriceNO());
            entity.setViePriceAbstract(o.getViePriceAbstract());
            entity.setPublishTime(DateUtil.format(DateUtil.date(o.getPublishTime()), "yyyy-MM-dd HH:mm"));
            entity.setAwardMemberId(o.getAwardMemberId());
            entity.setAwardRoleId(o.getAwardRoleId());
            entity.setAwardName(o.getAwardName());
            entity.setAwardTime(DateUtil.format(DateUtil.date(o.getAwardTime()), "yyyy-MM-dd HH:mm"));
            entity.setAwardAmount(o.getAwardAmount());
            entity.setOuterStatus("已完成");
            entity.setInnerStatus("已完成");
            entity.setQuotedPriceOrderId(o.getQuotedPriceOrderId());
            entity.setQuotedPriceOrderNo(o.getQuotedPriceOrderNo());
            return entity;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(result.getTotalElements(), resultList));
    }

    /**
     * 批量新增采购竞价合同
     * @author 伍将
     * @date 2021/3/15
     * @param addVOList: 新增请求参数
     * @return 操作结果
     **/
    @Transactional
    @Override
    public Wrapper<Void> addList(List<PurchaseViePriceAddVO> addVOList) {

        if (null != addVOList && addVOList.size() > 0) {

            // 验证新增数据是否已存在
            for (PurchaseViePriceAddVO addVO : addVOList) {
                PurchaseViePriceDO entity = repository.findData(addVO.getMemberId(), addVO.getRoleId(), addVO.getViePriceId(), addVO.getAwardMemberId(), addVO.getAwardRoleId());
                if (null != entity) {
                    throw new BusinessException(ResponseCode.CONTRACT_PURCHASE_VIE_PRICE_IS_EXIST);
                }
            }

            // 组装新增对象
            List<PurchaseViePriceDO> addList = addVOList.stream().map(o -> {
                PurchaseViePriceDO entity = new PurchaseViePriceDO();
                entity.setMemberId(o.getMemberId());
                entity.setRoleId(o.getRoleId());
                entity.setViePriceId(o.getViePriceId());
                entity.setViePriceNO(o.getViePriceNO());
                entity.setViePriceAbstract(o.getViePriceAbstract());
                entity.setPublishTime(o.getPublishTime());
                entity.setAwardMemberId(o.getAwardMemberId());
                entity.setAwardRoleId(o.getAwardRoleId());
                entity.setAwardName(o.getAwardName());
                entity.setAwardTime(o.getAwardTime());
                entity.setAwardAmount(o.getAwardAmount());
                entity.setInnerStatus(o.getInnerStatus());
                entity.setOuterStatus(o.getOuterStatus());
                entity.setIsCreate(CommonBooleanEnum.NO.getCode());
                entity.setCreateTime(System.currentTimeMillis());
                entity.setUpdateTime(System.currentTimeMillis());
                entity.setQuotedPriceOrderId(o.getId());
                entity.setQuotedPriceOrderNo(o.getOrderNo());
                return entity;
            }).collect(Collectors.toList());

            // 保存采购询价合同
            repository.saveAll(addList);
            //采购竞价提交+系统操作通知+1
            List<OperateNoticeVO> noticeVOS = addList.stream().map(inquiry -> {
                OperateNoticeVO noticeVO = new OperateNoticeVO();
                noticeVO.setMemberId(inquiry.getMemberId());
                noticeVO.setRoleId(inquiry.getRoleId());
                noticeVO.setDataSource(OperateDataSourceEnum.CONTRACT_MANAGE.getCode());
                noticeVO.setIncreaseOperateType(ContractManageOperateTypeEnum.TO_BE_CREATE_INQUIRY.getCode());
                noticeVO.setIncreaseCount(Constants.SYS_OPERATE_NOTICE_COUNT);
                noticeVO.setIncreaseTitle(inquiry.getViePriceAbstract());
                noticeVO.setIncreaseDataId(inquiry.getId());
                return noticeVO;
            }).collect(Collectors.toList());
            feignService.addSysOperateNoticeToMQ(noticeVOS);
            //发送消息
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                @Override
                public void afterCommit() {
                    List<SystemMessageRequest> msgList = addVOList.stream().map(o -> {
                        SystemMessageRequest request = new SystemMessageRequest();
                        request.setMemberId(o.getMemberId());
                        request.setRoleId(o.getRoleId());
                        request.setMessageNotice(MessageTemplateCode.contract_manage_purchase_bidding_create);
                        request.setParams(Stream.of(o.getViePriceNO(), o.getViePriceAbstract()).collect(Collectors.toList()));
                        return request;
                    }).collect(Collectors.toList());
                    feignService.batchSendSystemMessage(msgList);
                }
            });
        }

        return Wrapper.success();
    }


    /**
     * 检查采购竞价合同是否已创建合同
     * @author 伍将
     * @date 2021/3/15
     * @param user: 当前登录用户
     * @param viePriceId: 竞价单id
     * @param awardMemberId: 授标会员id
     * @param awardRoleId: 授标会员角色id
     * @return 操作结果
     **/
    @Override
    public PurchaseViePriceDO checkCreate(UserLoginCacheDTO user, Long viePriceId, Long awardMemberId, Long awardRoleId) {

        PurchaseViePriceDO entity = repository.findData(user.getMemberId(), user.getMemberRoleId(), viePriceId, awardMemberId, awardRoleId);
        if (null == entity) {
            throw new BusinessException(ResponseCode.CONTRACT_PURCHASE_VIE_PRICE_NOT_EXIST);
        }

        if (CommonBooleanEnum.YES.getCode().equals(entity.getIsCreate())) {
            throw new BusinessException(ResponseCode.CONTRACT_PURCHASE_VIE_PRICE_IS_CREATE);
        }

        return entity;
    }

    /**
     * 更新采购竞价合同创建状态
     * @author 伍将
     * @date 2021/3/15
     * @param user: 当前登录用户
     * @param viePriceId: 竞价单id
     * @param awardMemberId: 授标会员id
     * @param awardRoleId: 授标会员角色id
     * @param isCreate 创建合同：0-否，1-是
     * @return 操作结果
     **/
    @Override
    public Wrapper<Void> updateCreateStatus(UserLoginCacheDTO user, Long viePriceId, Long awardMemberId, Long awardRoleId, Integer isCreate) {

        PurchaseViePriceDO entity = repository.findData(user.getMemberId(), user.getMemberRoleId(), viePriceId, awardMemberId, awardRoleId);
        if (null == entity) {
            throw new BusinessException(ResponseCode.CONTRACT_PURCHASE_VIE_PRICE_NOT_EXIST);
        }

        if (CommonBooleanEnum.YES.getCode().equals(entity.getIsCreate()) && CommonBooleanEnum.YES.getCode().equals(isCreate)) {
            throw new BusinessException(ResponseCode.CONTRACT_PURCHASE_VIE_PRICE_IS_CREATE);
        }

        entity.setIsCreate(isCreate);
        entity.setUpdateTime(System.currentTimeMillis());
        repository.saveAndFlush(entity);

        return Wrapper.success();
    }
}
